package cz.mzk.funnylib.dao.db;

import cz.mzk.funnylib.dao.LibraryCheckDAO;
import cz.mzk.funnylib.entities.LibraryCheck;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Timestamp;
import java.util.List;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementCreator;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.support.GeneratedKeyHolder;

/**
 *
 * @author xrosecky
 */
public class LibraryCheckDAOImpl implements LibraryCheckDAO {

    private static String SELECT_LIBRARY_CHECKS_FOR_USER = "SELECT id, user_id, library_id, date FROM library_checks WHERE user_id = ?";
    private static String ADD_LIBRARY_CHECK = "INSERT INTO library_checks(user_id, library_id, date) VALUES(?, ?, ?)";
    private static String UPDATE_LIBRARY_CHECK = "UPDATE library_checks SET user_id = ?, library_id =?, date = ? WHERE id = ?";
    private JdbcTemplate jdbcTemplate;

    public LibraryCheckDAOImpl(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    public List<LibraryCheck> getLibraryChecksForUser(final Long userId) {
        return jdbcTemplate.query(SELECT_LIBRARY_CHECKS_FOR_USER, new Object[]{userId}, new LibraryCheckMapper());
    }

    public void persist(final LibraryCheck libraryCheck) {
        if (libraryCheck.getId() == null) {
            GeneratedKeyHolder keyHolder = new GeneratedKeyHolder();
            try {
                jdbcTemplate.update(new PreparedStatementCreator() {

                    @Override
                    public PreparedStatement createPreparedStatement(Connection conn) throws SQLException {
                        PreparedStatement preparedStatement = conn.prepareStatement(ADD_LIBRARY_CHECK, Statement.RETURN_GENERATED_KEYS);
                        preparedStatement.setLong(1, libraryCheck.getUserId());
                        preparedStatement.setLong(2, libraryCheck.getLibraryId());
                        preparedStatement.setTimestamp(3, new Timestamp(libraryCheck.getDate().getTime()));
                        return preparedStatement;
                    }
                }, keyHolder);
            } catch (DataIntegrityViolationException ex) {
                throw new RuntimeException("User already exists!", ex);
            }
            libraryCheck.setId(keyHolder.getKey().longValue());
        } else {
            jdbcTemplate.update(new PreparedStatementCreator() {

                @Override
                public PreparedStatement createPreparedStatement(Connection conn) throws SQLException {
                    PreparedStatement preparedStatement = conn.prepareStatement(UPDATE_LIBRARY_CHECK);
                        preparedStatement.setLong(1, libraryCheck.getUserId());
                        preparedStatement.setLong(2, libraryCheck.getLibraryId());
                        preparedStatement.setTimestamp(3, new Timestamp(libraryCheck.getDate().getTime()));
                        preparedStatement.setLong(4, libraryCheck.getId());
                    return preparedStatement;
                }
            });
        }
    }

    public class LibraryCheckMapper implements RowMapper<LibraryCheck> {

        @Override
        public LibraryCheck mapRow(ResultSet rs, int rowNum) throws SQLException {
            LibraryCheck libraryCheck = new LibraryCheck();
            libraryCheck.setId(rs.getLong(1));
            libraryCheck.setUserId(rs.getLong(2));
            libraryCheck.setLibraryId(rs.getLong(3));
            libraryCheck.setDate(rs.getTimestamp(4));
            return libraryCheck;
        }
    }
}
